/*
 * Copyright (c) 2009 Team TypeZero
 *
 * This file is part of ZebBowling
 *
 * ZebBowling is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * ZebBowling is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ZebBowling. If not, see <http://www.gnu.org/licenses/>.
 **/

package org.zebbowling.world;

import java.awt.Graphics;
import java.util.Arrays;
import org.zebbowling.control.ZBowlingCBS;

/**
 * This class is to be used when you are using SPOTs as your controllers instead
 * of the keyboard.
 *
 * @author markvismonte
 */
public class SpotBowlingLane extends BowlingLane {    

    public SpotBowlingLane(BowlingFrame frame) {
        super(frame);
        currPlayer = null;
        players = new BowlingPlayer[4];
        for (int i = 0; i < players.length; i++) 
            players[i] = new BowlingPlayer(i + 1);
        }

    public synchronized void startGame()
        {
        currentState = BowlingGameState.POWER_MODE;
        players = (BowlingPlayer[])Arrays.copyOfRange(players, 0, mode + 2);
        currPlayer = players[0];
        frame.setSize(BowlingFrame.GAME_WIDTH, BowlingFrame.GAME_HEIGHT);
        runner.setDelay(BowlingFrame.GAME_INTERVAL);
        }

    protected void powerState(Graphics graphToBack)
        {
        currPlayer.setPower(BowlingGameState.POWER_CURVE_OUT_OF_RANGE);
        currPlayer.setCurve(BowlingGameState.POWER_CURVE_OUT_OF_RANGE);
        lastState = currentState;
        currentState = BowlingGameState.CURVE_MODE;
        }

    protected void curveState(Graphics graphToBack) {
        graphToBack.drawString("Hold Spot Button Right and relase button", 10, 750);
        graphToBack.drawString("while performing a throwing motion", 20, 770);
        if (currPlayer.getCurve() != BowlingGameState.POWER_CURVE_OUT_OF_RANGE
                && currPlayer.getPower() != BowlingGameState.POWER_CURVE_OUT_OF_RANGE)
            {
            lastState = currentState;
            currentState = BowlingGameState.BOWL_MODE;
            }
        }

    protected void bowlState(Graphics graphToBack)
        {
        int pow = currPlayer.getPower(), cur = (int)(currPlayer.getCurve()-BowlingFrame.GAME_WIDTH/2);
        ball.setVel(cur/25, -pow/5 - 2);
        ball.update();
        if (((BowlingBall)(ball)).roll())
            {
            int score = 10 - bowlingPins.size();
            ball = new BowlingBall();
            lastState = currentState;
            currentState = BowlingGameState.POWER_MODE;
            rolls++;
            if (rolls > 1)
                score -= lastScore;
            currPlayer.addToSparesAndStrikes(score, turn);
            lastScore = score = 10 - bowlingPins.size();
            if (rolls > 1 || bowlingPins.size() == 0)
                {
                currPlayer.setScore(turn, score, 3 - rolls);
                if (player + 2 > players.length)
                    {
                    player = 0;
                    currPlayer = players[player];
                    turn++;
                    }
                else {
                    player++;
                    currPlayer = players[player];
                    }
                rolls = 0;
                addPins();
                }
            }
        }

    /**
     * Returns the {@linkplain BowlingPlayer} at index i in the {@code players}
     * array.
     *
     * @param i The index to get the {@code BowlingPlayer} from.
     * @return The {@code BowlingPlayer} at index i.
     */
    public synchronized BowlingPlayer getPlayer(int i) {
        if(i < 0)
            throw new IndexOutOfBoundsException("Negative index");
        if(i >= players.length)
            throw new IndexOutOfBoundsException("Index greater than length");
        return players[i];
        }

    /**
     *
     * @return The length of the player array
     * @deprecated This method was only used in {@linkplain ZBowlingCBS} which
     * is now deprecated.
     * @see ZBowlingCBS
     */
    public synchronized int getPlayerCount() {
        return players.length;
        }

    /**
     * Returns boolean indicating if the players array has been initialized.
     *
     * @return <tt>true</tt> if players array has been initialized else <tt>false</tt>
     * @deprecated This method was only used in {@linkplain ZBowlingCBS} which is
     * now deprecated.
     * @see ZBowlingCBS
     */
    public synchronized boolean playersMade() {
        return players != null;
        }

    }